package com.pxmeta.app.controller.community;

import cn.dev33.satoken.annotation.SaCheckDisable;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Maps;
import com.pxmeta.bot.service.IBotService;
import com.pxmeta.common.constant.HttpStatus;
import com.pxmeta.common.constant.UserVisitMode;
import com.pxmeta.common.core.domain.AjaxResult;
import com.pxmeta.common.enums.DynamicEnum;
import com.pxmeta.common.utils.SecurityUtils;
import com.pxmeta.common.utils.StringUtils;
import com.pxmeta.common.utils.ThreadPoolExecutorUtil;
import com.pxmeta.dynamic.entity.Dynamic;
import com.pxmeta.dynamic.entity.SearchHistory;
import com.pxmeta.dynamic.entity.dto.*;
import com.pxmeta.dynamic.entity.vo.CommunityTextVO;
import com.pxmeta.dynamic.entity.vo.DynamicDraftVO;
import com.pxmeta.dynamic.service.*;
import com.pxmeta.user.entity.UserVisit;
import com.pxmeta.user.entity.vo.NearbyUserVO;
import com.pxmeta.user.service.IUserVisitService;
import com.pxmeta.user.service.NearbyUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/community")
@RequiredArgsConstructor
@Api(value = "广场动态",tags = "广场动态")
@CrossOrigin
@Slf4j
public class DynamicController {

    public static final String TEXT = "为了保护用户创造的内容、维护良好的氛围，方便用户识有趣的人，碰心授权的社区管理员将依据本规范中的条款对注册碰心的用户和发布在碰心的内容进行管理。\n" +
            "采取的措施包括但不限于删除用户发布的内容、暂停或终止用户使用碰心或碰心部分功能的权利。所有有意的降低内容质量、伤害碰心氛围的行为 （下称「破坏」）都是不能容忍的！\n" +
            "多数情况下管理员也会先发出警告并给予用户改正自己不当行为的机会，但不表示我们在采取任何措施前必须首先发出警告。\n" +
            "违规行为界定\n" +
            "01、不友善的行为，主要表现为：臆测、羞辱、谩骂、攻击或其他不尊重用户在碰心发布的动态、文字、音频、图片、评论出版物及其写作背景的内容。羞辱、谩骂、攻击、骚扰、恐吓、威胁、诽谤碰心用户，或者其他发布在碰心并对其他用户造成严重影响的内容恶意煽动碰心用户攻击、孤立或以其他手段不友善地对待其他用户的内容。因民族、种族、宗教、性取向、性别、年龄、地域、生理特征等身份或者归类而歧视、侮辱、攻击他人的内容、泄露他人隐私，或者其他侵犯他人合法权益的内容。\n" +
            "温馨提示：碰心是一个可以自由发表自己想法的地方，但对于恶意发动态、评论或匿名评论公开辱骂他人的用户，特别是性骚扰他人的用户，我们会根据情结的严重程度，对其禁言或封号处理。那些实在没法拿出来看的图片，我就不多展示给大家看了！你们自己想象吧！不管你是开小号、发动态、发评论、匿名评论、还是私聊等其他方式，统统不允许，这里号召大家举报这些不友好的人，我们一定会及时处理！\n" +
            "02、发布垃圾广告信息：用户以推广曝光为目的，发布影响用户体验、扰乱碰心秩序的内容，或进行相关行为。主要表现为：多次发布包含售卖产品、提供服务、宣传推广内容的垃圾广告。包括但不限于以下几种形式：单个帐号多次发布包含垃圾广告的内容、多个广告帐号互相配合发布包含垃圾广告的内容、多次发布包含欺骗性外链的内容，如未注明的淘宝客链接、跳转网站等，诱骗用户点击链接，发布大量包含 SEO 推广链接、产品、品牌等内容获取不正当曝光。使用严重影响用户体验的违规手段进行恶意营销。包括但不限于以下几种形式：发布他人内容同时加入推广营销内容、发布包含欺骗性的恶意营销内容，如通过伪造经历、冒充他人等方式进行恶意营销、使用特殊符号、图片等方式规避垃圾广告内容审核的广告内容、恶意注册使用碰心帐号，包括但不限干机器注册、频繁注册、批量注册、滥用多个碰心帐号。\n" +
            "温馨提示 ：碰心是一个社交平台，但不是一个交易平台。我们会严格处理一切发广告的行为。卖減肥药、美白药、祛痘药、发兼职、买卖宠物......各种广告！还有私聊卖片的！真的太讨厌了！严重的会被封号！封号！封号！还有假的机器号，恶意营销，试图通过在碰心的一些行为获得曝光，牟取利益，这些都是我们严厉打击的对象！大家一定注意那些私聊发骚扰信息的虚假号，遇到这些人，大家一定要举报！\n" +
            "03、欺骗欺诈：以骗取他人财产为目的，发帖、与他人聊天，最终骗取他人财物：发布虚假信息，利用虚假信息与他人聊天，从中牟利：冒充海外党、外国友人、冒充无家可归的未成年、冒充买茶叶的小女孩、冒充一起团购坚果的小哥哥小姐姐。\n" +
            "温馨提示：我们会严格处理一切骗子！对骗子0容忍，全部封号！封号！封号！遇到骗子，大家一定要举报，将骗子绳之以法！希望小伙伴们可以火眼金睛！认出骗子，以防被骗。\n" +
            "04、恶意行为：滥用产品功能，进行影响用户体验，危及平台安全及损害他人权益的行为。主要表现为：冒充他人，通过照片、昵称、背景图等个人信息暗示自己与他人或机构相等同或有关联。重复发布干扰正常用户体验的内容。包括但不限于以下几种形式：重复的内容多次发布在不同话题下；频繁发布难以辦识涵义影响阅读体验的字符、数字等无意义乱码；骚扰他人，以发动态、评论、@他人、私聊等方式对他人反复发送重复或者相似的诉求。制作及传播外挂或者用于操作帐号功能的恶意程序或相关教程。发布含有潜在危险的内容，如钓鱼网站、木马、病毒网站、不明网站二维码等。恶意对抗行为，包括但不限于使用变体、谐音等方式规避安全审查，明知相关行为违反法律法规和社区规范仍然多次发布等。\n" +
            "05、违反法律法规：发布违反国家相关法律法规及「七条底线」、「九不准」\n" +
            "管理规定的信息，主要表现为：反对宪法所确定的基本原则、危害国家安全，泄露国家秘密，颠覆国家政权，破坏国家统一。损害国家荣誉和利益：煽动民族仇恨、民族歧视，破坏民族团结，侮辱、滥用英烈形象，否定英烈事迹，美化粉饰侵略战争行为的，破坏国家宗教政策，宣扬邪教和封建迷信，散布谣言，扰乱社会秩序，破坏社会稳定宣扬淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪煽动非法集会、结社、游行、示威、聚众扰乱社会秩序，诽谤他人，泄露他人隐私，侵害他人合法权益，含有法律、行政法规禁止的其他内容的信息\n" +
            "温馨提示：对于碰心中违法乱纪的行为，我们定会严惩不货！这些就不用多说了，大家都是遵纪守法的优秀同学，一定知道要怎么做的！\n" +
            "违规行为处理流程：站方通过主动发现和接受用户举报两种方式发现违规行为。用户可以使用碰心页面中的「举报」功能对涉嫌违规的行为和用户进行举报，违规的信息由碰心根据本规定直接处理。\n" +
            "碰心可以随着社区管理经验的不断丰富，出于维护碰心氛围和秩序的目的，不断完善本规定。";

    private final IDynamicService dynamicService;
    private final ICommunityDynamicUserLikeService dynamicUserLikeService;
    private final ISearchHistoryService searchHistoryService;
    private final RedisLockService redisLockService;

    private final IUserVisitService visitService;

    @SaCheckLogin
    @GetMapping("/getById")
    @ApiOperation("根据id获取动态详情")
    public AjaxResult<DynamicDTO> getById(@RequestParam Long id){
        Long userId = SecurityUtils.getUserId();
        DynamicDTO dto = dynamicService.getDynamicById(userId,id);
        return AjaxResult.success(dto);
    }


    @GetMapping("/getShareById")
    @ApiOperation("根据id获取分享动态")
    public AjaxResult<ShareDynamicDTO> getShareById(@RequestParam Long id){
        Long userId = 1556683869434081281L;
        DynamicDTO dto = dynamicService.getDynamicById(userId,id);
        Long hotId = dynamicService.getHotDynamicId(dto.getCircleId());
        log.info("热门动态id: "+ hotId);
        DynamicDTO hotDto = null;
        if (hotId == null) {
            hotId = dynamicService.getHotDynamicId(1L);
        }
        hotDto = dynamicService.getDynamicById(userId, hotId);
        ShareDynamicDTO shareDto = new ShareDynamicDTO();
        shareDto.setDynamic(dto);
        shareDto.setHotDynamic(hotDto);
        return AjaxResult.success(shareDto);
    }


    @GetMapping("/getCommunityManaText")
    @ApiOperation("获取社区管理规范文案")
    public AjaxResult<CommunityTextVO> getCommunityManaText(){
        CommunityTextVO vo = new CommunityTextVO();
        vo.setText(TEXT);
        vo.setTitle("碰心社区管理规范");
        return AjaxResult.success(vo);
    }

    @SaCheckLogin
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(name = "circleId", value = "圈子id"),
                    @ApiImplicitParam(name = "page", value = "页码"),
                    @ApiImplicitParam(name = "size", value = "每页记录数"),
                    @ApiImplicitParam(name = "type", value = "动态类型：1最新，2关注，3附近"),
                    @ApiImplicitParam(name = "userLng", value = "用户当前经度"),
                    @ApiImplicitParam(name = "userLnt", value = "用户当前纬度")
            }
    )
    @GetMapping("/getListByCircleId")
    @ApiOperation("根据圈子id获取动态列表")
    public AjaxResult<List<DynamicDTO>> getCommunities(@RequestParam Long circleId,
                                                         @RequestParam Integer page,
                                                         @RequestParam Integer size,
                                                         @RequestParam Integer type,
                                                       @RequestParam(required = false) Double userLng,
                                                       @RequestParam(required = false) Double userLnt){
        Long userId = SecurityUtils.getUserId();
        List<DynamicDTO> list= dynamicService.getByCircleId(circleId, userId, page, size, type,userLng,userLnt);
        return AjaxResult.success(list);
    }

    @SaCheckLogin
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(name = "topicId", value = "圈子id"),
                    @ApiImplicitParam(name = "page", value = "页码"),
                    @ApiImplicitParam(name = "size", value = "每页记录数"),
                    @ApiImplicitParam(name = "type", value = "动态类型：1最新，2推荐")
            }
    )
    @GetMapping("/getListByTopicId")
    @ApiOperation("根据话题id获取动态列表")
    public AjaxResult<List<DynamicDTO>> getDynamicByTopicId(@RequestParam Long topicId,
                                                       @RequestParam Integer page,
                                                       @RequestParam Integer size,
                                                            @RequestParam Integer type){
        Long userId = SecurityUtils.getUserId();
        List<DynamicDTO> list = dynamicService.getByTopicId(topicId, userId, page, size,type);
        return AjaxResult.success(list);
    }

    @SaCheckLogin
    @GetMapping("/searchDynamic")
    @ApiOperation("搜索动态")
    public AjaxResult<List<DynamicDTO>> searchDynamic(@RequestParam Long circleId,
                                    @RequestParam String keyword,
                                    @RequestParam Integer page,
                                    @RequestParam Integer size){
        Long userId = SecurityUtils.getUserId();
        List<DynamicDTO> list = dynamicService.search(userId, circleId, keyword, page, size);
        return AjaxResult.success(list);
    }

    @SaCheckLogin
    @DeleteMapping("/removeDynamic")
    @ApiOperation("删除动态")
    public AjaxResult removeDynamic(@RequestParam Long dynamicId){
        Long userId = SecurityUtils.getUserId();
        Dynamic dynamic = dynamicService.getById(dynamicId);
        if (null == dynamic){
            return AjaxResult.error(HttpStatus.DATA_NOT_FOUND_ERROR,"该动态已被删除！");
        }
        if (userId.equals(dynamic.getUserId())){
            dynamicService.deleteDynamic(dynamicId);
            return AjaxResult.success();
        }
        return AjaxResult.error("删除失败！");
    }

    @SaCheckLogin
    @ApiOperation("获取上次草稿内容")
    @PostMapping("/getDynamicDraft")
    public AjaxResult<DynamicDraftVO> getDynamicDraft(){
        Long userId = SecurityUtils.getUserId();
        DynamicDraftVO draft = dynamicService.getDynamicDraft(userId);
        return AjaxResult.success(draft);
    }

    @SaCheckLogin
    @ApiOperation(value = "发布动态")
    @PostMapping("/publishDynamic")
    @SaCheckDisable
    public AjaxResult<?> publishDynamic(@RequestBody CreateDynamicDTO dto){
        //添加分布式锁。
        Long userId = SecurityUtils.getUserId();
        Long dynamicId = null;
        String lockKey = "publishLockKey:"+userId;
        String lock = redisLockService.lock(lockKey, 1000, 200);
        if (StringUtils.isNotBlank(lock)){
            dynamicId = dynamicService.publish(userId, dto);
        }else {
            AjaxResult.error("发布频率太快啦，休息一会再来吧！");
        }
//        Long finalDynamicId = dynamicId;
//        Runnable task = ()-> {
//            if (CollectionUtils.isNotEmpty(dto.getRemindUserIdList()) &&
//                    dto.getRemindUserIdList().contains(1L)){ //如果包含机器人
//                //自动回复
//                botService.replyDynamic(finalDynamicId);
//            }
//        };
//        ThreadPoolExecutorUtil.submit(task);

        return AjaxResult.success();
    }

    @SaCheckLogin
    @PostMapping(value = "/like")
    @ApiOperation(value = "点赞/取消点赞")
    @SaCheckDisable
    public AjaxResult like(@RequestBody DynamicLikeDTO dto){
        Long userId = SecurityUtils.getUserId();
        dynamicUserLikeService.like(dto,userId);
        return AjaxResult.success();
    }



    @SaCheckLogin
    @ApiOperation("查看别人动态")
    @GetMapping("/viewUserDynamic")
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(name = "circleId", value = "圈子id"),
                    @ApiImplicitParam(name = "targetUserId", value = "目标用户id"),
            }
    )
    public AjaxResult viewUserDynamic(@RequestParam(required = false) Long circleId,
                                      @RequestParam Long targetUserId,
                                      @RequestParam(required = false,defaultValue = "1") Integer page,
                                      @RequestParam(required = false, defaultValue = "20") Integer size){
        List<DynamicDTO> dto = dynamicService.getByUserId(targetUserId, page, size);
        Long userId = SecurityUtils.getUserId();
        //增加访客记录
        if (!userId.equals(targetUserId)){
            visitService.save(UserVisit.builder().userId(userId).targetUserId(targetUserId).visitMode(UserVisitMode.HOME).visitDate(LocalDateTime.now()).build());
        }
        return AjaxResult.success(dto);
    }


    @SaCheckLogin
    @PostMapping("/dislikeDynamic")
    @ApiOperation("动态不感兴趣")
    public AjaxResult dislikeDynamic(@RequestBody DynamicDislikeDTO dto){
        Long userId = SecurityUtils.getUserId();
        dynamicService.dislike(dto,userId);
        return AjaxResult.success();
    }

    @SaCheckLogin
    @PutMapping("/updatePermission")
    @ApiOperation("修改动态权限")
    public AjaxResult updatePermission(@RequestBody @Valid UpdatePermissionDTO dto){
        Long userId = SecurityUtils.getUserId();
        dynamicService.updatePermission(dto,userId);
        return AjaxResult.success();
    }


    @SaCheckLogin
    @GetMapping("/getSearchHistory")
    @ApiOperation("获取动态搜索历史")
    public AjaxResult<List<SearchHistory> > getSearchHistory(@RequestParam Long circleId){

        Long userId = SecurityUtils.getUserId();
        LambdaQueryWrapper<SearchHistory> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SearchHistory::getUserId, userId)
                .eq(SearchHistory::getCircleId, circleId)
                .eq(SearchHistory::getType, DynamicEnum.TYPE_DYNAMIC.getType())
                .orderByDesc(SearchHistory::getUpdateTime);
        List<SearchHistory> list = searchHistoryService.list(wrapper);
        return AjaxResult.success(list);
    }


    @SaCheckLogin
    @GetMapping("/shareDynamic")
    @ApiOperation("分享动态")
    public AjaxResult shareDynamic(@RequestParam Long dynamicId){
        Long userId = SecurityUtils.getUserId();
        Dynamic dynamic = dynamicService.getById(dynamicId);
        Integer shareCount = dynamic.getShareCount();
        shareCount ++;
        dynamic.setShareCount(shareCount);
        dynamicService.updateById(dynamic);
        String url = "https://h5.pengxinmeta.com/dynamic?id="+dynamicId+"&userId="+userId;
        Map<String, Object> map = Maps.newHashMap();
        map.put("shareUrl",url);
        return AjaxResult.success(map);
    }
}
